using System;
using System.Collections.Generic;
using System.Text;
using System.Management.Automation  ;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Administration;

namespace Community.SharePoint.Commands
{
    
    
       
    public abstract class SiteBaseCommand : Cmdlet 
    {
        internal List<SPSite> _allSites;
         internal List<SPSite> _matchingSites;
        internal SPSite[] _input;
        internal string[] _url;
        internal bool _disableWildCardReplacement;
        internal MatchMode _Mode;

        [Parameter(Position = 0, 
            ParameterSetName = "ByUrl",
           Mandatory = false,
           ValueFromPipelineByPropertyName = true,
           HelpMessage = "URL parameter accepts one or more comma-separated urls. Supports wildcards")]
        public String[] Url
        {
            get { return _url; }
            set
            {
                _Mode = MatchMode.ByURL;
                _url = value;
            }
        }

        [Parameter(ParameterSetName = "InputObject",
          Mandatory = true,
          ValueFromPipeline = true)]
        public SPSite[] InputObject
        {
            get
            {
                return _input;
            }
            set
            {
                this._Mode = MatchMode.ByInput;
                this._input = value;
            }
        }
        [Parameter(
           Mandatory = false,
           ParameterSetName = "LiteralName",
           ValueFromPipeline = false,
           ValueFromPipelineByPropertyName = false)]
        public String[] LiteralUrl
        {
            get { return _url; }
            set
            {
                _Mode = MatchMode.ByURL;
                _disableWildCardReplacement = true;
                _url = value;
            }
        }

        internal List<SPSite> AllSites
        {
            get
            {
                if (_allSites == null)
                {
                    _allSites = GetAllSites();
                }
                return _allSites;
            }
        }

        
        protected SiteBaseCommand()
        {
            _matchingSites = new List<SPSite>();
        }
     
        private List<SPSite> GetAllSites()
        {

            List<SPSite> allSites = new List<SPSite>();
            SPFarm farm = SPFarm.Local;

            SPWebServiceCollection webServs = new SPWebServiceCollection(farm);
            foreach (SPWebService webService in webServs)
            {
                SPWebApplicationCollection webApps = webService.WebApplications;
                foreach (SPWebApplication webApp in webApps)
                {
                    SPSiteCollection sites = webApp.Sites;
                    foreach (SPSite site in sites)
                    {
                        allSites.Add(site);
                    }
                }
            }
            return allSites;
        }

        internal List<SPSite> MatchingSites()
           {
            this._matchingSites.Clear();

            switch (this._Mode)
            {
                case MatchMode.ByInput:
                    {
                        this.RetrieveMatchingSitesByInput();
                        break;
                    }

                default:
                    {
                        this.RetrieveMatchingSitesByURL();
                        break;
                    }
            }
            
            return this._matchingSites;
        }

        private void RetrieveMatchingSitesByURL()
        {
            if (this._url == null)
            {
                _matchingSites = GetAllSites();
            }
            else
            {
                foreach (string s in _url)
                {
                    if (_disableWildCardReplacement || !(WildcardPattern.ContainsWildcardCharacters(s)))
                    {
                        using (SPSite site = new SPSite(s))
                        {
                            _matchingSites.Add(site);
                        }
                    }
                    else
                    {
                        WildcardPattern wildCard = new WildcardPattern(s, WildcardOptions.IgnoreCase);

                        foreach (SPSite site in AllSites)
                        {
                            if (wildCard.IsMatch(site.Url))
                            {
                                _matchingSites.Add(site);
                            }
                        }
                    }
                }
            }
        }

        private void RetrieveMatchingSitesByInput()
        {
            if (this._input == null)
            {
                throw new System.Exception("Add Error handler here");
            }
            else
            {
                foreach (SPSite site in _input)
                {
                    _matchingSites.Add(site);
                   }
            }
        }
    }
}
